﻿using PmSoft.Utilities.Sm4;
using AutoMapper;
using ManagementApi.Models;
using ManagementApi.Models.App;
using ManagementApi.Services;
using ManagementApi.TreeParty.SMS;
using Microsoft.AspNetCore.Mvc;
using Modules.Base;
using Modules.Common;
using Modules.Project;
using Modules.System.Attachment;
using Newtonsoft.Json;
using Org.BouncyCastle.Utilities.Encoders;
using PmSoft.Entity;
using PmSoft.FileStorage;
using System.Security.Cryptography;
using static Modules.CheckIn.CheckInDetailConstants;
using PmSoft.ApplicationContext;
using Modules.Reports;
using Modules.CheckIn;
using Modules.SMS;
using Pipelines.Sockets.Unofficial.Arenas;
using PmSoft.Utilities.Sm3;
using Modules.System.Security;
using Modules.System.User;
using Modules.FaceScan;

namespace ManagementApi.Controllers
{
    [ApiController]
    [Route("/api/v1/test")]
    public class TestController : ControllerBase
    {
        private readonly IFileStorage fileStorage;
        private readonly FacePhotoService personFaceService;
        private readonly AppService appService;
        private readonly AttachmentService attachmentService;
        private readonly ProjectService projectService;
        private readonly SerialNumberService serialNumberService;
        private readonly ISMSService sMSService;
        private readonly ILogger logger;
        private readonly IMapper mapper;
        private readonly IApplicationContext applicationContext;

        public TestController(IFileStorage fileStorage, FacePhotoService personFaceService, AppService appService, AttachmentService attachmentService, ProjectService projectService, SerialNumberService serialNumberService, ISMSService sMSService, ILogger<TestController> logger, IMapper mapper,
            IApplicationContext applicationContext)
        {
            this.fileStorage = fileStorage;
            this.personFaceService = personFaceService;
            this.appService = appService;
            this.attachmentService = attachmentService;
            this.projectService = projectService;
            this.serialNumberService = serialNumberService;
            this.sMSService = sMSService;
            this.logger = logger;
            this.mapper = mapper;
            this.applicationContext = applicationContext;
        }

        [HttpGet("TestSm3")]
        public async Task<ApiResult> TestSm3(string input = "123456")
        {
            string output = SM3Util.Encrypt(input);
            return ApiResult.Success(output);
        }

        [HttpGet("TestPwd")]
        public async Task<ApiResult> TestPwd(string input = "123456")
        {
            string pwd = SM3Util.Encrypt(input);
            string enPwd = SecurityPasswordHelper.EncodePassword(pwd, UserPasswordFormat.SM4);
            return ApiResult.Success(enPwd);
        }

        /// <summary>
        /// 测试文件在线预览地址
        /// </summary>
        /// <returns></returns>
        [HttpGet("TestFileUrl")]
        public async Task<ApiResult> TestFileUrl()
        {
            string url = await fileStorage.PresignedGetObject("project", "LockOut/10/05a291c318a2467aaaf0e0bb22f5dea8.docx");
            return ApiResult.Success(url);
        }

        [HttpGet("sendsms")]
        public async Task<ApiResult> SendSms()
        {
            string code = SmsBuidler.Instance().GetValidateCode();
            SmsModel smsModel = SmsBuidler.Instance().ValidateCode(code);
            smsModel.Code = code;
            applicationContext.GetService<SmsSendLogService>().Send("13368114441", smsModel);
            return ApiResult.Success($"发送成功,code={code}");
        }

        [HttpGet("validateSmsCode")]
        public async Task<ApiResult> ValidateSmsCode(string code)
        {
            if (applicationContext.GetService<SmsSendLogService>().Validate("13368114441", code, MsgType.VerificationCode))
                return ApiResult.Success("验证成功");
            else
                return ApiResult.Failure("验证失败");
        }

        /// <summary>
        /// 测试短信1
        /// </summary>
        //[HttpGet("smsTest")]
        //public void testSMS()
        //{
        //    logger.LogInformation($"测试短信接口开始1");

        //    string code = SmsBuidler.Instance().GetValidateCode();
        //    SmsModel smsModel = SmsBuidler.Instance().ValidateCode(code);
        //    smsModel.Code = code;
        //    logger.LogInformation($"测试短信接口开始2");
        //    lXTSMSService.SendMessage("13368114441", smsModel);

        //    //sMSService.SendMessage(mobiles, smsModel);
        //}

        /// <summary>
        /// 测试AutoMapper
        /// </summary>
        [HttpGet("AutoMapper")]
        public void AutoMapper()
        {
            class1 class1 = new() { Type = 数据来源.考勤机 };
            class2 cls = mapper.Map<class2>(class1);
        }

        /// <summary>
        /// 根据身份证号码获取头像
        /// </summary>
        /// <param name="cardNo"></param>
        /// <returns></returns>
        [HttpGet("GetCardNoImageToBase64/{cardNo}")]
        public ApiResult GetCardNoImageToBase64(string cardNo)
        {
            string base64PhotoStr = "";
            byte[] objectData = personFaceService.GetCardPhotoData(cardNo);
            if (objectData.Length > 0)
                base64PhotoStr = Base64.ToBase64String(objectData);
            return ApiResult.Success(base64PhotoStr);
        }

        /// <summary>
        /// 生成token
        /// </summary>
        /// <param name="securityId">安全id</param>
        /// <param name="cardNumber">身份证号</param>
        /// <returns></returns>
        [HttpGet("GetSm4CryptoToken")]
        public ApiResult<string> GetSm4CryptoToken(int securityId, string cardNumber)
        {
            return ApiResult<string>.Success(appService.GetToken(securityId, UserType.Worker, cardNumber));
        }

        ///// <summary>
        ///// 参数加密
        ///// </summary>
        ///// <param name="info"></param>
        ///// <returns></returns>
        //[HttpPost("GetSm4Crypto")]
        //public object GetSm4Crypto([FromBody] ProjectGroupMemberInfo info)
        //{
        //    var resu = Sm4Crypto.UrlEncode(JsonConvert.SerializeObject(info));
        //    return resu;
        //}

        ///// <summary>
        ///// 下载
        ///// </summary>
        ///// <returns></returns>
        //[HttpGet("DownLoad")]
        //public ApiResult DownLoad()
        //{
        //    var minio = minIoService.Create();
        //    MinioHelper.FGetObject(minio, "person", "511602199501191317.jpg", @"C:\Users\lp\Desktop\511602199501191317.jpg");
        //    return ApiResult.Success("成功");
        //}

        /// <summary>
        /// 获取文件
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetFile")]
        public async Task<IActionResult> GetFileUrl()
        {
            string aaa = "";
            byte[] objectData = fileStorage.GetFileAsync(FileBuckets.Person, $"500229199407042978/500229199407042978_20231013094452955.jpg").GetAwaiter().GetResult();

            if (objectData.Length > 0)
                aaa = Base64.ToBase64String(objectData);

            var result = File(objectData, "image/jpeg", false);
            return result;
        }

        /// <summary>
        /// 获取ip地址
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetIp")]
        public async Task<ApiResult> GetIp()
        {
            var host = HttpContext.Request.Host.Host;
            var port = HttpContext.Request.Host.Port;
            return ApiResult.Success(host + ":" + port);
        }

        [HttpPost("FileUpload222/{id}")]
        public ApiResult FileUpload(int? id)
        {
            if (Request.Form.Files.Count > 0)
            {
                attachmentService.CreateTemporaryAsync(Request.Form.Files[0]).GetAwaiter();
            }
            return ApiResult.Success("上传成功");
        }

        /// <summary>
        /// 获取最大项目流水号
        /// </summary>
        /// <param name="areaCode"></param>
        /// <returns></returns>
        [HttpGet("projectmaxNumber")]
        public ApiResult<object> testProjectNumber(int areaCode = 540321)
        {
            var 最大流水号 = projectService.GetProjectInfoByMaxSerialNumber(areaCode);
            var 项目编号 = projectService.GetProjectNum(areaCode);
            return ApiResult<object>.Success(new { 最大流水号 = 最大流水号, 项目编号 = 项目编号 });
        }

        /// <summary>
        /// 获取编号测试
        /// </summary>
        /// <param name="areaCode"></param>
        /// <returns></returns>
        [HttpGet("getnumber")]
        public ApiResult<object> getnumber(SerialNumberType type)
        {
            return ApiResult<object>.Success(serialNumberService.GetSerialNumber(type, "", 22));
        }

        /// <summary>
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost("aesdecrypt")]
        public ApiResult<object> AESDecrypt(AESForm data)
        {
            string decData = ReaderEncrypt.Decrypt(data.data, false, data.encKey);
            if (string.IsNullOrEmpty(data.encKey))
            {
                decData = ReaderEncrypt.Decrypt(data.data);
            }

            return ApiResult<object>.Success(decData);
        }

        /// <summary>
        /// 测试生成项目月报表
        /// </summary>
        /// <returns></returns>
        [HttpGet("GenerateProjectMonthReport")]
        public ApiResult<string> GenerateProjectMonthReport(DateTime? date)
        {
            var reportProjectMonthService = applicationContext.GetService<ReportProjectMonthService>();
            if (!date.HasValue)
                date = DateTime.Now;
            reportProjectMonthService.Generate(212, date.Value);
            //int month = Convert.ToInt32(date.Value.ToString("yyyyMM"));
            //IEnumerable<int> projectIds;
            //while ((projectIds = reportProjectMonthService.GetProjectIdsInNoUpdate(month)).Count() > 0)
            //{
            //    foreach (int projectId in projectIds)
            //    {
            //        try
            //        {
            //            reportProjectMonthService.Generate(projectId, date.Value);
            //        }
            //        catch (Exception ex)
            //        {
            //            logger.LogError(ex, "项目月统计报表执行失败，projectId={0}，错误消息={1}", projectId, ex.Message);
            //            throw;
            //        }
            //    }
            //}
            return ApiResult<string>.Success("执行完成");
        }

        /// <summary>
        /// 测试班组成员考勤按月统计
        /// </summary>
        /// <returns></returns>
        [HttpGet("generateGroupMemberMonthReport")]
        public ApiResult<string> GenerateGroupMemberMonthReport(DateTime? date)
        {
            if (!date.HasValue)
                date = DateTime.Now;
            var checkinWorkHoursService = applicationContext.GetService<CheckinWorkHoursService>();
            IEnumerable<int> memberIds;
            while ((memberIds = checkinWorkHoursService.GetMemberIdsInNoUpdate(date.Value)).Count() > 0)
            {
                try
                {
                    checkinWorkHoursService.Generate(memberIds, date.Value);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "人员考勤每日更新月报表生成失败");
                    throw;
                }
            }
            return ApiResult<string>.Success("执行完成");
        }

        [HttpGet("generateProjectDayReport")]
        public ApiResult<string> GenerateProjectDayReport(DateTime? date)
        {
            if (!date.HasValue)
                date = DateTime.Now;
            var reportProjectGroupDaysService = applicationContext.GetService<ReportProjectGroupDaysService>();
            IEnumerable<int> projectIds;
            while ((projectIds = reportProjectGroupDaysService.GetProjectIdsInNoUpdate(date.Value)).Count() > 0)
            {
                foreach (int id in projectIds)
                {
                    try
                    {
                        reportProjectGroupDaysService.Generate(id, date.Value);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "项目考勤日报表生成失败");
                        throw;
                    }
                }
            }
            return ApiResult<string>.Success("执行完成");
        }

        /// <summary>
        /// 测试POST请求
        /// </summary>
        /// <param name="codes"></param>
        /// <returns></returns>
        [HttpPost("testRequrst")]
        public ApiResult<object> TestRequrst(List<string> codes) {
            var val = codes;
            return ApiResult<object>.Success("执行完成");
        }

        public class AESForm
        {
            public string data { get; set; }
            public string encKey { get; set; }
        }
    }
}